﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using PSTS.Models;
using PSTS.UI.Commands;
using PSTS.UI.Views.Pages;

namespace PSTS.UI.ViewModels
{
     public class TestPassingPageViewModel:DependencyObject
     {
         private DispatcherTimer _dispatcherTimer;
         private Action<Page> _completeTestAction;

         public TestPassingPageViewModel(IEnumerable<Question> questions,  Action<Page> completeAction)
         {
             QuestionsList = questions.ToList();
             QuestionNumbers = new List<int>();
             QuestionPagesList = new List<QuestionPage>();
             for (int i = 1; i <= QuestionsList.Count; i++)
             {
                 QuestionNumbers.Add(i);
                 QuestionPagesList.Add(new QuestionPage(QuestionsList[i - 1]));
                 SelectedQuestionNumber = QuestionNumbers[0];
             }
             _completeTestAction = completeAction;
         }

         public TestPassingPageViewModel(IEnumerable<Question> questions, Action<Page> completeAction, DateTime timerTime)
         {
             QuestionsList = questions.ToList();
             QuestionNumbers=new List<int>();
             QuestionPagesList = new List<QuestionPage>();
             for (int i = 1; i <= QuestionsList.Count; i++)
             {
                 QuestionNumbers.Add(i);
                 QuestionPagesList.Add(new QuestionPage(QuestionsList[i-1]));
             }
             _completeTestAction = completeAction;

             TimerTime = timerTime;
             TimerVisibility = Visibility.Visible;

             SelectedQuestionNumber = QuestionNumbers[0];
             _dispatcherTimer = new DispatcherTimer();
             _dispatcherTimer.Tick += new EventHandler(OnDispatcherTimer_Tick);
             _dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
             _dispatcherTimer.Start();
         }

         public List<Question> QuestionsList { get; set; }
         public List<QuestionPage> QuestionPagesList { get; set; } 
         public CommandBinding CompleteTestCommandBinding { get; set; }

         public List<int> QuestionNumbers { get; set; }

         public DateTime TimerTime
         {
             get { return (DateTime)GetValue(TimerTimeProperty); }
             set { SetValue(TimerTimeProperty, value); }
         }
         public static readonly DependencyProperty TimerTimeProperty = DependencyProperty.Register(
                                                                         "TimerTime",
                                                                         typeof(DateTime),
                                                                         typeof(TestPassingPageViewModel),
                                                                         new PropertyMetadata(null));
         public Visibility TimerVisibility
         {
             get { return (Visibility)GetValue(TimerVisibilityProperty); }
             set { SetValue(TimerVisibilityProperty, value); }
         }
         public static readonly DependencyProperty TimerVisibilityProperty = DependencyProperty.Register(
                                                                         "TimerVisibility",
                                                                         typeof(Visibility),
                                                                         typeof(TestPassingPageViewModel),
                                                                         new PropertyMetadata(Visibility.Hidden));


         public int SelectedQuestionNumber
         {
             get { return (int)GetValue(SelectedQuestionNumberProperty); }
             set { SetValue(SelectedQuestionNumberProperty, value); }
         }
         public static readonly DependencyProperty SelectedQuestionNumberProperty = DependencyProperty.Register(
                                                                         "SelectedQuestionNumber",
                                                                         typeof(int),
                                                                         typeof(TestPassingPageViewModel),
                                                                         new PropertyMetadata(SelectedQuestionNumber_ChangedCallback));
         public QuestionPage SelectedQuestion
         {
             get { return (QuestionPage)GetValue(SelectedQuestionProperty); }
             set { SetValue(SelectedQuestionProperty, value); }
         }
         public static readonly DependencyProperty SelectedQuestionProperty = DependencyProperty.Register(
                                                                         "SelectedQuestion",
                                                                         typeof(QuestionPage),
                                                                         typeof(TestPassingPageViewModel));





         private static void SelectedQuestionNumber_ChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
         {
             var viewModel = sender as TestPassingPageViewModel;
             if (viewModel != null)
             {
                 viewModel.SelectedQuestion = viewModel.QuestionPagesList[viewModel.SelectedQuestionNumber - 1];
                 //viewModel.SelectedQuestion = new QuestionPage(viewModel.QuestionsList[viewModel.SelectedQuestionNumber - 1]);
             }
         }


         private void OnDispatcherTimer_Tick(object sender, EventArgs e)
         {
             TimerTime = TimerTime.AddSeconds(-1);
             if (TimerTime.Minute == 0 && TimerTime.Second == 0)
             {
                 ComleteTest();
             }
         }

         public void ComleteTest()
         {
             if (_dispatcherTimer!=null)
                 _dispatcherTimer.Stop();
             foreach (var page in QuestionPagesList)
             {
                 page.Confirm();
             }

             _completeTestAction(new ResultPage(new ResultPageViewModel(this)));
         }


         public void AddCommands(TestPassingPage page)
         {
             page.CommandBindings.Add(new CommandBinding(
                 PSTSCommands.NextQuestionCommand,
                 NextQuestionCommand_Executed,
                 NextQuestionCommand_CanExecute
                 ));

             page.CommandBindings.Add(new CommandBinding(
                 PSTSCommands.PreviousQuestionCommand,
                 PreviousQuestionCommand_Executed,
                 PreviousQuestionCommand_CanExecute
                 ));

             page.CommandBindings.Add(new CommandBinding(
                 PSTSCommands.ConfirmQuestionCommand,
                 ConfirmQuestionCommand_Executed,
                 ConfirmQuestionCommand_CanExecute
                 ));
             if (CompleteTestCommandBinding != null)
             {
                 page.CommandBindings.Add(CompleteTestCommandBinding);
             }
         }

         private void ConfirmQuestionCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
         {
             e.CanExecute = SelectedQuestion!=null && SelectedQuestion.Answers.Any(x => x.IsChecked == true) && !SelectedQuestion.IsConfirmed;
         }

         private void ConfirmQuestionCommand_Executed(object sender, ExecutedRoutedEventArgs e)
         {
             SelectedQuestion.Confirm();
         }

         private void PreviousQuestionCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
         {
             e.CanExecute = SelectedQuestionNumber > 1;
         }

         private void PreviousQuestionCommand_Executed(object sender, ExecutedRoutedEventArgs e)
         {
             SelectedQuestionNumber--;
         }

         private void NextQuestionCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
         {
             e.CanExecute = SelectedQuestionNumber < QuestionsList.Count;
         }

         private void NextQuestionCommand_Executed(object sender, ExecutedRoutedEventArgs e)
         {
             SelectedQuestionNumber++;
         }
    } 
}
